VSOA : Vehicle SOA
VSOA is the abbreviation of Vehicle SOA presented by ACOINFO, VSOA provides a reliable, Real-Time SOA (Service Oriented Architecture) framework, this framework has multi-language and multi-environment implementation, developers can use this framework to build a distributed service model.
VSOA includes the following features:
- Support resource tagging of unified URL
- Support URL matching subscribe and publish model
- Support Real-Time Remote Procedure Call
- Support parallel multiple command sequences
- Support reliable and unreliable data publishing and datagram
- Support multi-channel full-duplex high speed parallel data stream
- Support network QoS control
- Easily implement server fault-tolerant design
- Supports multiple language bindings
VSOA is a dual-channel communication protocol, using both TCP and UDP, among which the API marked with quick
uses the UDP channel. The quick channel is used for high-frequency data update channels. Due to the high data update frequency, the requirements for communication reliability are not strict. It should be noted that UDP channel cannot pass through NAT network, so please do not use quick channel in NAT network.
The total url and payload length of the VSOA data packet cannot exceed 256KBytes - 20Bytes and 65507Bytes - 20Bytes on quick channel, so if you need to send a large amount of data, you can use the VSOA data stream.
User can use the following code to import the vsoa
module.
var vsoa = require('vsoa');
Support
The following shows vsoa
module APIs available for each permissions.
User Mode | Privilege Mode | |
---|---|---|
vsoa.Server | ● | ● |
server.close | ● | ● |
server.start | ● | ● |
server.count | ● | ● |
server.address | ● | ● |
server.onclient | ● | ● |
server.ondata | ● | ● |
server.publish | ● | ● |
server.isSubscribed | ● | ● |
server.syncer | ● | ● |
server.sendTimeout | ● | ● |
server.working | ● | ● |
server.createStream | ● | ● |
vsoa.Client | ● | ● |
client.connect | ● | ● |
client.close | ● | ● |
client.ping | ● | ● |
client.subscribe | ● | ● |
client.unsubscribe | ● | ● |
client.call | ● | ● |
client.fetch | ● | ● |
client.datagram | ● | ● |
client.connected | ● | ● |
client.createStream | ● | ● |
client.sendTimeout | ● | ● |
vsoa.Regulator | ● | ● |
vsoa.Regulator.slot | ● | ● |
regulator.close | ● | ● |
regulator.slot | ● | ● |
regulator.unslot | ● | ● |
regulator.period | ● | ● |
vsoa.Proxy | ● | ● |
proxy.start | ● | ● |
proxy.close | ● | ● |
proxy.add | ● | ● |
proxy.delete | ● | ● |
vsoa.Position | ● | ● |
position.start | ● | ● |
position.stop | ● | ● |
position.close | ● | ● |
position.onquery | ● | ● |
vsoa.Position.server | ● | ● |
vsoa.lookup | ● | ● |
vsoa.code | ● | ● |
vsoa.method | ● | ● |
vsoa.fetch | ● | ● |
VSOA Server Class
new vsoa.Server(opt)
opt
{Object} Server configuration.- Returns: {Object} VSOA server object.
To create a VSOA server, opt
must contain the following members:
info
{Object} Server information description.name
{String} Server name.
If the server requires a connection password, opt
needs to contain the following members:
passwd
{String} Connection password. Optional.
If the server does not need to automatically parse the JSON in the payload, you can set the following options:
rawParam
{Boolean} Whether to automatically parse the JSON in the payload. Only valid forRPC
,PUBLISH
andDATAGRAM
packet. default: false.
Example
var server = new vsoa.Server({ info: { name: 'Test server' } });
VSOA Server Object
The VSOA server object inherits from EventEmitter
, and the on()
method can be used to add processing callbacks for different services.
server.close([removeListeners])
removeListeners
{Boolean} Remove all listeners default: false
Close VSOA server.
server.start(saddr[, tlsOpt])
saddr
{Object} Server socket address.tlsOpt
{Object} TLS security configuration. Optional.
saddr
is the server address, it needs to contain the following members:
domain
{Integer} Address domain. Refer totcp
orsocket
module.addr
{String} IP address.port
{Integer} TCP port.dev
{String} The name of the network inteface bound to the socket. Optional.backlog
{Integer} TCP server backlog. Optional.
Start the server, if the startup fails, an exception will be thrown. If the server is a secure connection server, you need to set the tlsOpt
parameter, please refer to the tls
module description.
Example
var Tcp = require('tcp');
// Start server
server.start(Tcp.sockaddr(Tcp.INADDR_ANY, 3000));
If the port bound at start is 0
, the system will automatically assign a port. At this time, the VSOA server TCP and UDP ports are different, and the client needs to use version 1.0.1
or later to support.
server.count([link])
link
{Boolean} Those without successful password verification will also be counted.- Returns: {Integer} Current clients count.
Get the number of connected clients.
server.address()
- Returns: {Object} Server address.
Get the current server TCP / TLS address, the return type is socket address.
server.onclient
- {Function}
This function will be called when a client is connected or disconnected. The arguments of this callback function are as follows:
cli
{Object} Remote client.connect
{Boolean} Connect or disconnect.
Example
var server = new vsoa.Server(...);
server.onclient = function(cli, connect) {
if (connect) {
console.log('New client connected!', cli.address().addr);
} else {
console.log('Client lost!', cli.address().addr);
}
}
server.ondata
- {Function}
This callback is called when the server receives a DATAGRAM type packet. The arguments of this callback function are as follows:
cli
{Object} Remote client.url
{String} This datagram URL.payload
{Object} This datagram payload data.quick
{Boolean} Whether this datagram comes from the quick channel.
The payload
is the datagram payload, and the payload
contains the following members:
param
{Object | String} Parameters of this datagram. Optional.data
{Buffer} Data for this datagram. Optional.
Example
var server = new vsoa.Server(...);
server.ondata = function(cli, url, payload) {
console.log(url, JSON.stringify(payload.param));
}
server.publish(url[, payload][, quick])
url
{String} This event URL.payload
{Object} This message payload data.quick
{Boolean} Whether to use the quick publish channel. default: false.
Publish a message, all clients subscribed to this URL will receive this message. If a large number of high-frequency releases are required and delivery is not guaranteed, the quick
parameter can be set to true
.
The payload
contains the following members:
param
{Object | String} Parameters of this RPC request. Optional.data
{Buffer} Data for this publish. Optional.offset
{Integer} Ifdata
exists, this member indicates the offset ofdata
. Optional.length
{Integer} Ifdata
exists, this member indicates the length ofdata
. Optional.
URL matching: URL uses '/'
as a separator, for example: '/a/b/c'
, if the client subscribes to '/a/'
, the server publish '/a'
, '/a/b'
or '/a/b/c'
message, the client will be received.
Example
var server = new vsoa.Server(...);
server.publish('/a/b/c');
server.publish('/a/b/c', { param: { hello: 'hello' } });
server.publish('/a/b/c', { param: { hello: 'hello' }, data: new Buffer([1, 2, 3]) });
If a large number of high-frequency publish are required and delivery is not guaranteed, quick publish can be used. But the quick type publish cannot traverse a NAT network, so the quick publish interface is not allowed in a NAT network. quick publish uses a different channel than publish, quick publish does not guarantee the order of arrival.
server.isSubscribed(url)
url
{String} URL.- Returns: {Boolean} Whether the specified URL is subscribed by clients.
Whether the specified URL is subscribed. When the return value is true
, it means that the specified URL is subscribed by at least one client.
server.syncer(cli, request, payload, target[, setter])
cli
{Object} Remote client object.request
{Object} Remote RPC request.url
{String} Request URL.seqno
{Integer} Command sequence number.method
{Integer} Operation method.
payload
{Object} Request payload.target
{Object} The target object that needs data synchronization.setter
{Function} Do parameter checking and set target's callback function.param
{Object} Requestpayload.param
.payload
{Object} Request payload.- Returns: {Integer} Returns
0
for successful settings, other values represent errors.
This function helps VSOA server to synchronize data and reduce data synchronization code. If request method is get, this function will automatically reply to the RPC request. If request method is set, this function will check whether the setter
is valid. If the setter
is valid, the setter
is responsible for updating the target
, and if the setter
is invalid, it will be updated directly with payload.param
target, this function will automatically reply to the RPC remote client and generate the corresponding publish operation.
The payload
is the RPC request payload, and the payload
contains the following members:
param
{Object | String} Parameters of this RPC request. Optional.data
{Buffer} Data for this RPC request. Optional.
Example
var server = new vsoa.Server(...);
var data = { foo: 0 };
server.on('/foo', function(cli, request, payload) {
server.syncer(cli, request, payload, data, param => {
if (typeof param.foo === 'number') {
data.foo = param.foo;
return vsoa.code.SUCCESS;
} else {
return vsoa.code.ARGUMENTS;
}
});
});
server.sendTimeout(timeout[, curclis])
timeout
{Integer} Send timeout.curclis
{Boolean} Whether to set the currently connected client at the same time.
When the server is created, it will use the default send timeout (100
ms), this function is used to modify this setting, all clients will use this setting by default.
server.working
- {Boolean}
Get whether the current server is working.
server.createStream([timeout])
timeout
{Integer} Timeout time for waiting for client stream connection, default: 10000ms.- Returns: {Stream.Duplex} Duplex stream.
Create a stream to wait for the client stream to connect, this object has inherited from Stream.Duplex
, you can refer to the Stream
related documents for operation.
The members of this stream object extending Stream.Duplex
object are as follows:
close
{Function} Close this stream.tunid
{Integer} This stream tunnel id, The client stream can connect to this server stream through thistunid
.
In addition to the events defined by the standard Stream.Duplex
, this object also generates the following additional events:
'timeout'
When the server stream does not receive the client stream connection request within the specified timeout period, the'timeout'
event will be generated at this time, and the stream will be automatically closed at the same time.'connect'
This event is generated when the client stream successfully connects with the current stream.
Example
var server = new vsoa.Server(...);
var buffer = new Buffer([0, 1, 2, 3, 4, 5, 6]);
server.on('/a/b/c', function(cli, request, payload) {
var stream = server.createStream();
cli.reply(0, request.seqno, stream.tunid);
stream.on('connect', () => {
stream.write(buffer);
stream.close();
});
stream.on('timeout', () => {
console.log('No client connect stream!');
});
});
VSOA Server Events
The VSOA server object inherits from EventEmitter
, and the on()
method can be used to add processing callbacks for different services.
Client Command URL
cli
{Object} Remote client.request
{Object} Remote client request.url
{String} Request URL.seqno
{Integer} Command sequence number.method
{Integer} Operation method.
payload
{Object} Command payload. Optional.param
{Object | String} Payload parameter. Optional.data
{Buffer} Payload data. Optional.
When a remote client generates an RPC request, the server will receive the corresponding request event, usually the event name is the requested URL matched.
Possible values of method
include vsoa.method.GET
(0
) and vsoa.method.SET
(1
).
The server can reply to RPC calls through the cli.reply
function.
Example
var server = new vsoa.Server(...);
// Echo payload
server.on('/echo', function(cli, request, payload) {
cli.reply(0, request.seqno, payload);
});
// Strictly match '/a/b/c' path
server.on('/a/b/c', function(cli, request, payload) {
cli.reply(0, request.seqno, payload);
});
// Match '/a/b/c' and '/a/b/c/...'
server.on('/a/b/c/', function(cli, request, payload) {
cli.reply(0, request.seqno, payload);
});
// Default match
server.on('/', function(cli, request, payload) {
cli.reply(0, request.seqno, payload);
});
// Delay echo
server.on('/delayecho', function(cli, request, payload) {
setTimeout(function() {
cli.reply(0, request.seqno, payload);
}, 1000);
});
RPC URL match rules
PATH | RPC match rules |
---|---|
"/" | Default URL listener. |
"/a/b/c" | Only handle "/a/b/c" path call. |
"/a/b/c/" | Handle "/a/b/c" and "/a/b/c/..." all path calls. |
VSOA Remote Client Object
cli.authed
- {Boolean}
Whether the client is authorized. When a client connects to the server and has passed the password verification, cli.authed
is true
. At this time, the client can receive the publish message. If the server wants to perform independent client authorization , you can set cli.authed
to false
in the onclient
callback, then the client cannot receive the publish message until the client passes the independent authorization program designed by the server.
Example
var server = new vsoa.Server(...);
server.onclient = function(cli, connect) {
if (connect) {
cli.authed = false; // We need independent authorization.
}
};
server.on('/auth', function(cli, request, payload) {
if (payload && /* Independent Authorization Verify */) {
cli.authed = true;
/* The authorization verification is successful,
* and the server's publish information can be received */
cli.reply(0, request.seqno);
} else {
cli.reply(AUTH_ERROR_CODE, request.seqno);
}
});
This feature is available in VSOA 1.0.7 and above.
cli.close()
Close this remote client connection.
cli.address()
- Returns: {Object} Remote client address.
Get this remote client address, the return type is socket address.
cli.isSubscribed(url)
url
{String} URL.- Returns: {Boolean} Whether the specified URL is subscribed by this client.
Whether the specified URL is subscribed.
cli.reply(code, seqno[, payload][, tunid])
code
{Integer} Return status code.seqno
{Integer} Command sequence number.payload
{Object} This reply payload data.param
{Object | String} Parameters of this message. Optional.data
{Buffer} Data for this message. Optional.offset
{Integer} Ifdata
exists, this member indicates the offset ofdata
. Optional.length
{Integer} Ifdata
exists, this member indicates the length ofdata
. Optional.
tunid
{Integer} Server tunnel stream id.
Server RPC reply, The valid value of code
is 0
- 255
, where 0
means success, and other values mean failure, where vsoa.code
contains the following failure values, and the user-defined failure value is recommended to be 128
~ 254
.
Status Code | Value |
---|---|
vsoa.code.SUCCESS | 0 |
vsoa.code.PASSWORD | 1 |
vsoa.code.ARGUMENTS | 2 |
vsoa.code.INVALID_URL | 3 |
vsoa.code.NO_RESPONDING | 4 |
vsoa.code.NO_PERMISSIONS | 5 |
vsoa.code.NO_MEMORY | 6 |
cli.datagram(url, payload[, quick])
url
{String} This datagram URL.payload
{Object} This reply payload data.param
{Object | String} Parameters of this datagram. Optional.data
{Buffer} Data for this datagram. Optional.offset
{Integer} Ifdata
exists, this member indicates the offset ofdata
. Optional.length
{Integer} Ifdata
exists, this member indicates the length ofdata
. Optional.
quick
{Boolean} Whether to use the quick channel. default: false.
Send a DATAGRAM packet to the client.
cli.setKeepAlive(idle)
idle
{Integer} Idle time in milliseconds.
Set a connection keep alive timer for this remote client, when it fails 3 times in a row, the client connection is considered disconnected.
Example
var server = new vsoa.Server(...);
server.onclient = function(cli, connect) {
if (connect) {
cli.setKeepAlive(5000);
}
}
cli.priority(prio)
prio
{Integer} New priority.
Set the specified remote client priority, the allowed priority range is 0
~ 5
, 0
is the lowest priority, 5
is the highest priority, and the initial priority of each client is 0
. The priority controls the order in which the publish is sent, and the underlying network packet QoS, please set according to the situation.
Example
var server = new vsoa.Server(...);
server.onclient = function(cli, connect) {
if (connect) {
// If this client is an important client.
cli.priority(3);
}
}
cli.sendTimeout(timeout)
timeout
{Integer | Undefined} Set network send timeout(ms).
Set the client packet sending timeout, the default is server global send timeout setting (500
ms) in JSRE. NodeJS does not have a send timeout setting by default.
VSOA Remote Client Event
The VSOA remote client object inherits from EventEmitter
, and the on()
method can be used to listen the following event.
subscribe
url
{String | Array} Subscribe URL.
This client is subscribed to the specified URL event.
unsubscribe
url
{String | Array | Null} Unsubscribe URL.
This client is unsubscribed to the specified URL event. If the URL is null
, it means unsubscribe from all events.
VSOA Client Class
new vsoa.Client([opt])
opt
{Object} Client options.
Create a VSOA client, if you need a connection password, you can specify it in opt.passwd
.
opt
can also contain the following members:
pingInterval
{Integer} Ping interval time, must be greater than 10ms. Optional.pingTimeout
{Integer} Ping timeout, must be less or equal thanpingInterval
default: same aspingInterval
. Optional.pingLost
{Integer} How many consecutive ping timeouts will drop the connection. default: 3.pingTurbo
{Integer} Fast ping period. must be less or equal thanpingInterval
,pingInterval
should be an integer multiple ofpingTurbo
. Optional.
If you set pingInterval
, after the client connects to the server, it will immediately start periodic ping operations, and always check the communication link and whether the server is normal.
If the client does not need to automatically parse the JSON in the payload, you can set the following options:
rawParam
{Boolean} Whether to automatically parse the JSON in the payload. Only valid forRPC
,PUBLISH
andDATAGRAM
packet. default: false.
Example
var client1 = new vsoa.Client();
var client2 = new vsoa.Client({ passwd: '123456' });
var client3 = new vsoa.Client({ passwd: '123456', pingInterval: 5000, pingTimeout: 3000, pingLost: 5 });
When there is an RPC call pending, and if there is data packet loss, and the client and server need to do their best to perform TCP fast retransmission at this time, you can set this pingTurbo
parameter, the minimum value is 25ms. 0
means disable turbo ping.
Example
var client4 = new vsoa.Client({ passwd: '123456', pingInterval: 5000, pingTimeout: 3000, pingLost: 5, `pingTurbo`: 200 });
VSOA Client Object
client.connect(saddr[, callback][, tlsOpt][, timeout])
saddr
{Object} Server socket address.callback
{Function} Connection result callback function. Optional.error
{Error} Specify error message when connection error.info
{Object | String} Server information obtained when the connection is successful.
tlsOpt
{Object} TLS security configuration. Optional.timeout
{Integer} Connection timeout. default: 10000ms.
Connect to the specified VSOA server.
saddr
is the server address, it needs to contain the following members:
domain
{Integer} Address domain. Refer totcp
orsocket
module.addr
{String} IP address.port
{Integer} TCP port.
If the server is a secure connection server, you need to set the tlsOpt
parameter, please refer to the tls
module description.
Example
var Tcp = require('tcp');
var saddr = Tcp.sockaddr('127.0.0.1', 3000);
var client = new vsoa.Client();
client.connect(saddr, function(error, info) {
if (error) {
console.error('Connect error:', error);
if (error.status) {
console.error('Error status code:', error.status);
}
} else {
console.log('Connect OK server info:', JSON.stringify(info));
}
});
client.connect(url[, callback][, tlsOpt][, timeout])
url
{String} Server URL.callback
{Function} Connection result callback function.error
{Error} Specify error message when connection error.info
{Object | String} Server information obtained when the connection is successful.
tlsOpt
{Object} TLS security configuration.timeout
{Integer} Connection timeout. default: 10000ms.
Connect to the specified VSOA server.
Example
var client = new vsoa.Client();
client.connect('vsoa://vsoa.acoinfo.com', function(error, info) {
if (error) {
console.error('Connect error:', error);
if (error.status) {
console.error('Error status code:', error.status);
}
} else {
console.log('Connect OK server info:', JSON.stringify(info));
}
});
client.close()
Close the current client. After this client is closed, it is allowed to call the client.connect
method to reconnect to the server.
client.ping([callback[, timeout]])
callback
{Function} Ping reply callback.error
{Error} If an error occurs, specify the error message and error status.
timeout
{Integer} Response timeout. default: 60000ms.
Use Ping / Echo mechanism to check whether the server connection is normal.
Example
client.ping(function(error) {
if (error) {
// connection lost, reconnect...
}
});
Under normal circumstances, TCP connection disconnection can be obtained by listening to the client's 'error'
event, and periodic Ping operations can detect physical connection failure errors.
client.subscribe(url[, callback[, timeout]])
url
{String | Array} Events that need to be subscribed.callback
{Function} Subscription results.error
{Error} If there is an error, indicate the error message and error status.
timeout
Timeout. default: 60000ms.
Subscribe to the specified event (URL), when the server sends the corresponding event, the Client can receive the event.
url
indicates the event, VSOA event matching is prefix matching, for example, when the client subscribes to the '/a/b/'
event, then the '/a/b'
or '/a/b/c'
event can be received.
Example
client.on('message', function(url, payload) {
console.log('Received URL:', url, JSON.stringify(payload));
});
// Single subscription
client.subscribe('/a', function(error) {
if (error) {
console.error('Subscribe error', error);
}
});
// Multi subscription
client.subscribe(['/a', '/b', '/c'], function(error) {
if (error) {
console.error('Subscribe error', error);
}
});
Subscribe URL match rules
PATH | Subscribe match rules |
---|---|
"/" | Catch all publish message. |
"/a/b/c" | Only catch "/a/b/c" publish message. |
"/a/b/c/" | Catch "/a/b/c" and "/a/b/c/..." all publish message. |
client.unsubscribe([url[, callback[, timeout]]])
url
{String | Array | Null} Events that need to be unsubscribed.callback
{Function} Unsubscription results.error
{Error} If there is an error, indicate the error message and error status.
timeout
Timeout. default: 60000ms.
Unsubscribe the specified event, if url
is null
, unsubscribe all events.
client.call(url[, opt[, payload]][, callback[, timeout]])
url
{String} RPC command url.opt
{Object} RPC options.method
{Integer | String} RPC method. default: vsoa.method.GET.
payload
{Object} RPC payload. Optional.callback
{Function} RPC callback function.error
{Error} If there is an error, indicate the error message and error status.payload
{Object} Server reply payload. Optional.tunid
{Integer} Server reply tunnel stream id. Optional.
timeout
{Integer} Timeout. default: 60000ms.
Make an RPC call. The value of opt.method
is vsoa.method.GET
or vsoa.method.SET
. Version 1.5.0 or above supports string type, and the value is 'SET'
or 'GET'
.
The payload
is the message payload, and the payload
contains the following members:
param
{Object | String} Parameters of this message. Optional.data
{Buffer} Data for this message. Optional.offset
{Integer} Ifdata
exists, this member indicates the offset ofdata
. Optional.length
{Integer} Ifdata
exists, this member indicates the length ofdata
. Optional.
Example
- Simple call
client.call('/a/b/c', function(error) {
if (error) {
console.error('RPC call error:', error);
if (error.status) {
console.error('Error status code:', error.status);
}
}
});
- Setting
client.call('/a/b/c', { method: vsoa.method.SET }, {
param: { hello: 'hello' }
}, function(error) {
if (error) {
console.error('RPC call error:', error);
if (error.status) {
console.error('Error status code:', error.status);
}
}
});
- Get stream data
client.call('/a/b/c', function(error, payload, tunid) {
if (tunid) {
var stream = client.createStream(tunid);
stream.on('data', (chunk) => {
console.log('RECV:', chunk.toString('hex'));
});
stream.on('timeout', () => {
console.log('Stream connect error!');
});
}
});
The error
generated by the client If error.message
is 'status'
, you can get the status code returned by the server through error.status
.
Example
if (error.message === 'status') {
console.log(error.status);
}
// Or
if (error.status) {
console.log(error.status);
}
async client.fetch(url[, opt[, payload]][, timeout])
url
{String} RPC command url.opt
{Object} RPC options. (No payload can be omitted)method
{Integer | String} RPC method. default: vsoa.method.GET.
payload
{Object} RPC payload. Optional.timeout
{Integer} Timeout. default: 60000ms.- Returns: {Object} Promise result.
Make an RPC call with asynchronous mode. Normally, the return value object contains the following members:
payload
{Object} Server reply payload. Optional.tunid
{Integer} Server reply tunnel stream id. Optional.
If an error occurs, an exception is thrown, and the .status
member of the error
object can be detected to obtain the error code returned by the server. If there is a payload when the error occurs, the .payload
member of the error
object saves the payload information returned by the server.
The value of opt.method
is vsoa.method.GET
or vsoa.method.SET
. Version 1.5.0 or above supports string type, and the value is 'SET'
or 'GET'
.
Example
async function test() {
try {
var { payload, tunid } = await client.fetch('/a/b/c');
} catch (error) {
return console.error(error.message, error.status, error.payload);
}
console.log(JSON.stringify(payload));
}
// Or:
client.fetch('/a/b/c').then((payload, tunid) => {
console.log(JSON.stringify(payload));
}, error => console.error(error.message, error.status));
client.datagram(url, payload[, quick])
url
{String} Datagram url.payload
{Object} Payload.quick
{Boolean} Whether use quick channel. default: false.
Client sends DATAGRAM packet to server. This communication server does not confirm and does not guarantee successful communication.
client.createStream(tunid[, timeout])
tunid
{Integer} Server tunnel stream id.timeout
{Integer} Timeout. default: 10000ms.- Returns: {Stream.Duplex} Duplex stream.
Create a stream to connect with server stream, this object has inherited from Stream.Duplex
, you can refer to the Stream
related documents for operation.
The members of this stream object extending Stream.Duplex
object are as follows:
close
{Function} Close this stream.
In addition to the events defined by the standard Stream.Duplex
, this object also generates the following additional events:
'timeout'
When the server stream does not connect the server stream connection request within the specified timeout period, the'timeout'
event will be generated at this time, and the stream will be automatically closed at the same time.'connect'
This event is generated when the client stream successfully connects with the server stream.
client.sendTimeout(timeout)
timeout
{Integer | Undefined} Set network send timeout(ms).
Set the client packet sending timeout, the default waiting for the sending buffer to be valid is 100
ms in JSRE. NodeJS does not have a send timeout setting by default.
VSOA Client Events
The VSOA client object inherits from EventEmitter
, and the on()
method can be used to listen the following event.
message
url
{String} Server event URL.payload
{Object} Server event payload. Optional.quick
{Boolean} Is it a quick publish message.
For events published by the server, if this client subscribes to the relevant URL, then when the server publishes the corresponding event, this client will be received.
Example
client.on('message', function(url, payload, quick) {
console.log('Event', url, 'received');
});
datagram
url
{String} Server datagram URL.payload
{Object} Server datagram payload.quick
{Boolean} Whether this datagram comes from the quick channel.
The client receives the DATAGRAM packet sent by the server.
subscribe
url
{String | Array} Server event URL.
This client successfully subscribed to the specified event.
Example
client.on('subscribe', function(url) {
console.log('Event', url, 'subscribed');
});
unsubscribe
url
{String | Array | Null} Server event URL.
This client successfully unsubscribed from the specified event. If null
, the client unsubscribe all subscriptions.
connect
info
{Object | String} Server information.
This client successfully connected to the server.
Example
client.on('connect', function(info) {
console.log('Connect to server success:', JSON.stringify(info));
});
error
error
{Error} Error message.
When the client generates an error, it will receive this event. When receiving this event, the user can call client.close
to close the client, and the client object can be call client.connect
again.
Example
client.on('error', function(error) {
console.log('Client error:', error);
client.close();
});
The possible errors are as follows:
Error Message | Has Status | Description |
---|---|---|
'no responding' | Server is not responding | |
'status' | ● | Server responded with an error status |
'ping timeout' | Periodic automatic ping timeout | |
'send timeout' | Send timeout | |
'no network' | Server connection lost | |
'no connection' | Network is not connected | |
'insufficient resources' | Insufficient network resources | |
'parser failed' | Packet parser error | |
'closed' | Client is closed |
VSOA Regulator Class
VSOA regulator provides the function of changing the speed of client subscription data. For example, the server publish period is 100ms, and the regulator can slow down the speed to receive once every 1000ms.
new vsoa.Regulator(client, period)
client
{VsoaClient} VSOA client object.period
{Integer} Fastest update period.- Returns: {Object} VSOA regulator object.
Create a VSOA regulator, period
cannot be less than 1ms.
Example
var regulator = new vsoa.Regulator(client, 1000);
vsoa.Regulator.slot(client, period, url)
client
{VsoaClient} VSOA client object.period
{Integer} Fastest update period.url
{String} Legal URL string.- Returns: {Object} VSOA regulator object.
This function is equivalent to the following code:
function(client, period, url) {
var regulator = new Regulator(client, period);
regulator.slot(url);
return regulator;
}
VSOA Regulator Object
regulator.close()
Close VSOA regulator. This object cannot be used again.
regulator.slot(url)
url
{String} Legal URL string.- Returns: {Object} VSOA regulator object.
Set a URL that needs to be changed. This URL can be a precise URL or a wildcard URL.
regulator.unslot(url)
url
{String} Legal URL string.- Returns: {Object} VSOA regulator object.
Delete a URL that regulator.slot()
has been called before.
For example, the server '/foo'
url publishes very quickly, and we need to reduce the speed to 1s. You can use the following code:
var regulator = new vsoa.Regulator(client, 1000);
regulator.slot('/foo').on('message', (url, payload, quick) => {
// The frequency here is called at most once every 1 second.
});
If you need to speed down the publish reception of all URLs starting with '/foo'
, you can use '/foo/'
as the slot url.
regulator.period(period)
period
{Integer} New fastest update period.- Returns: {Object} VSOA regulator object.
Change the period parameter of regulator.
VSOA Regulator Events
The VSOA regulator object inherits from EventEmitter
, and the on()
method can be used to listen the following event.
message
url
{String} Server event URL.payload
{Object} Server event payload. Optional.quick
{Boolean} Is it a quick publish message.
After changing the speed of the publish message event, developers do not need to repeatedly listen to the client’s message
event.
VSOA Proxy Class
VSOA proxy provides a multi-server proxy function, which can abstract multiple microservices into one microservice entry.
new vsoa.Proxy([opt])
opt
{Object} Server configuration.- Returns: {Object} VSOA proxy object.
Create a VSOA server for proxying, opt
is an argument to new vsoa.Server()
.
VSOA Proxy Object
proxy.close()
Close VSOA proxy.
proxy.start(saddr[, tlsOpt])
saddr
{Object} Server socket address.tlsOpt
{Object} TLS security configuration. Optional.
Start the proxy server.
proxy.add(prefix, opt, saddr[, tlsOpt])
prefix
{String} Path prefixes starting with'/'
.opt
{Object} Options for connecting to remote servers.saddr
{Object | String} Remote server socket address or domain name.tlsOpt
{Object} TLS security configuration. Optional.
Create a proxy rule. The optional parameters of opt
are as follows:
passwd
{String} Remote server password.pingInterval
{Integer} Ping interval time, must be greater than 10ms. Optional.pingTimeout
{Integer} Ping timeout, must be less thanpingInterval
default: half ofpingInterval
. Optional.pingLost
{Integer} How many consecutive ping timeouts will drop the connection. default: 3.timeout
{Integer} RPC call timeout.
Example
var proxy = new vsoa.Proxy();
// Start
proxy.start(Tcp.sockaddr(Tcp.INADDR_ANY, 3000));
// Add rule
proxy.add('/s1', { timeout: 5000 }, 'vsoa://s1');
proxy.add('/s2', { timeout: 5000 }, 'vsoa://s2');
proxy.delete(prefix)
prefix
{String} Path prefixes starting with'/'
.
Delete an added rule.
Example
proxy.delete('/s1');
VSOA Position Server Class
VSOA Position Server provides the function of querying VSOA server address by service name, similar to DNS server.
new vsoa.Position(table, saddr)
table
{Array} Server address table.saddr
{Object} Position server socket address.- Returns: {Object} Position server object.
To create a VSOA Position Server, each item of the table array needs to meet the following requirements:
name
{String} VSOA server name.domain
{Integer} Address domain Refer totcp
orsocket
module.addr
{String} IP address.port
{Integer} TCP port.security
{Boolean} Whether the server is a TLS secure connection.
Example
var position = new vsoa.Position([
{ name: 's1', domain: 2, addr: '192.168.0.1', port: 1000, security: false },
{ name: 's2', domain: 2, addr: '192.168.0.2', port: 2000, security: false },
{ name: 's3', domain: 2, addr: '192.168.0.3', port: 3000, security: false },
], { domain: 2, addr: '0.0.0.0', port: 1234 });
// Or
var position = new vsoa.Position([], {
domain: 2, addr: '0.0.0.0', port: 1234
});
VSOA Position Server Object
position.start()
Start the VSOA position server.
position.stop()
Stop the VSOA position server.
position.close()
Close the postion server, this object can no longer be used after the server is closed.
position.onquery
- {Function}
This function will be called when the VSOA server cannot be found in the initialization table of the position server. The arguments of this callback function are as follows:
name
{String} The name of the VSOA server to be queried.domain
{Integer} Query the server address of the specified domain.undefined
means any domain.callback
{Function} Query result callback.res
{Object} Query resultundefined
means not found.
Example
position.onquery = function(name, domain, callback) {
if (name === 's1') {
callback({
domain: 2, addr: '192.168.0.1', port: 1000, security: false
});
} else {
callback(undefined);
}
}
VSOA Position Query
vsoa.Position.server(saddr)
saddr
{Object} Position server address.
Set the VSOA position query server address, and subsequent query operations will use this address for query.
If position server is specified, only the specified server will be queried, If the position server address has not been specified, this function will first use the environment variable VSOA_POS_SERVER
to query, if not found, it will use the server query configured in /etc/vsoa.pos
(C:\Windows\System32\drivers\etc\vsoa.pos
in Windows).
vsoa.lookup(name, callback[, domain])
name
{String} VSOA server name.callback
{Function} Query callback.error
{Error} Error message.saddr
{Object} VSOA server socket address.
domain
{Integer} Query the server address of the specified domain. default: any domain.
Query the network socket address corresponding to a VSOA service.
Example
vsoa.lookup('s1', function(error, saddr) {
if (saddr) {
console.log('VSOA Server s1 address:', JSON.stringify(saddr));
}
});
VSOA Status Code
Similar to HTTP, the server responds with a status code to the client.
vsoa.code
- {Array}
VSOA status code, the valid value of code
is 0
~ 255
, where 0
means success, and other values mean failure, where vsoa.code
contains the following failure values, and the user-defined failure value is recommended to be 128
~ 254
.
Status Code | Value | Description |
---|---|---|
vsoa.code.SUCCESS | 0 | Call succeeded |
vsoa.code.PASSWORD | 1 | Wrong password |
vsoa.code.ARGUMENTS | 2 | Parameter error |
vsoa.code.INVALID_URL | 3 | Invalid URL |
vsoa.code.NO_RESPONDING | 4 | Server not responding |
vsoa.code.NO_PERMISSIONS | 5 | No permission |
vsoa.code.NO_MEMORY | 6 | Out of memory |
vsoa.code.PROXY | 7 | Proxy error (payload.param.error indicates the error message) |
VSOA RPC Method
Similar to HTTP, the client requests the server with the method parameter.
vsoa.method
- {Integer}
Method | Value |
---|---|
vsoa.method.GET | 0 |
vsoa.method.SET | 1 |
VSOA Single Remote Call
async vsoa.fetch(url[, opt[, payload]][, timeout])
url
{String} RPC command url.opt
{Object} RPC options.method
{Integer | String} RPC method. default: vsoa.method.GET.passwd
{String} Server password. default: no password.tlsOpt
{Object} TLS security configuration. Optional.
payload
{Object} RPC payload. Optional.timeout
{Integer} Timeout. default: 60000ms.- Returns: {Object} Promise result.
Make an RPC call with asynchronous mode. Normally, the return value object contains the following members:
payload
{Object} Server reply payload. Optional.tunid
{Integer} Server reply tunnel stream id. Optional.info
{Object | String} Server information.
If an error occurs, an exception is thrown, and the .status
member of the error
object can be detected to obtain the error code returned by the server.
The value of opt.method
is vsoa.method.GET
or vsoa.method.SET
. Version 1.5.0 or above supports string type, and the value is 'SET'
or 'GET'
.
Example
// Fetch server /foo data
vsoa.fetch('vsoa://vsoa.example.com/foo').then(result => {
console.info('Fetch /foo OK:', JSON.stringify(result));
}).catch(error => {
console.error('Fetch /foo ERROR:', error.message, error.status);
});
// Or:
async function test() {
var result = await vsoa.fetch('vsoa://vsoa.example.com/foo', { passwd: '123456' });
console.info('Fetch /foo OK:', JSON.stringify(result));
}